using System;
using System.Data;
using DataGeneration.Domain.Helpers;

namespace DataGeneration.Domain.DataAccessLayer
{
    /// <summary>
    /// DataAccess
    /// </summary>
    public class DataAccess : IDisposable
    {
        /// <summary>
        /// Gets or sets the connection.
        /// </summary>
        /// <value>The connection.</value>
        public IDbConnection Connection { get; set; }

        /// <summary>
        /// Gets or sets the command.
        /// </summary>
        /// <value>The command.</value>
        public IDbCommand Command { get; set; }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Close();
        }

        /// <summary>
        /// This method provides an avenue through which the client can intitiate the release of consumed data access resources such as a database connection.
        /// </summary>
        public void Close()
        {
            Connection.Close();
        }

        /// <summary>
        /// Executes the command.
        /// </summary>
        public void ExecuteCommand()
        {
            Command.ExecuteNonQuery();
        }

        /// <summary>
        /// Executes the scalar.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T ExecuteScalar<T>()
        {
            T objectToReturn = Typehelper.EnsureType<T>(Command.ExecuteScalar());
            return objectToReturn;
        }

        /// <summary>
        /// Executes the scalar.
        /// </summary>
        /// <returns></returns>
        public object ExecuteScalar()
        {
            object objectToReturn = Command.ExecuteScalar();
            return objectToReturn;
        }

        /// <summary>
        /// Executes the reader.
        /// </summary>
        /// <returns></returns>
        public IDataReader ExecuteDataReader()
        {
            IDataReader dataReader = Command.ExecuteReader();
            return dataReader;
        }

        /// <summary>
        /// Gets or sets the transaction.
        /// </summary>
        /// <value>The transaction.</value>
        public IDbTransaction Transaction { get; set; }

        /// <summary>
        /// Opens the connection.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <returns></returns>
        public static IDbConnection OpenConnection(string connectionString)
        {
            if (ParameterizedAppSettings.DatabaseType.Equals(SupportedDatabase.Oracle))
            {
                return OracleInitializer.OpenConnection(connectionString);
            }

            return SqlServerInitializer.OpenConnection(connectionString);
        }

        public static IDbConnection OpenConnection(string connectionString,SupportedDatabase supportedDatabase)
        {
            if (supportedDatabase.Equals(SupportedDatabase.Oracle))
            {
                return OracleInitializer.OpenConnection(connectionString);
            }

            return SqlServerInitializer.OpenConnection(connectionString);
        }

        /// <summary>
        /// Initializes the command.
        /// </summary>
        public void InitializeCommand(string commandName, CommandType commandType)
        {
            if (ParameterizedAppSettings.DatabaseType.Equals(SupportedDatabase.Oracle))
            {
                Command = OracleInitializer.InitializeCommand(commandName, commandType, Connection);
            }
            else
            {
                Command = SqlServerInitializer.InitializeCommand(commandName, commandType, Connection);
            }

            if (Transaction != null)
            {
                Command.Transaction = Transaction;
            }
        }

    }
}